// ==========================================================================
// gin-sns自动生成业务逻辑层相关代码，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:54 +0800 CST
// path: app/service/module/follow_service.go
// author：jon
// ==========================================================================
package module

import (
	"errors"
	"gin-sns/app/dao/module/follow"
	"gin-sns/app/dao/module/user"
	"gin-sns/app/model"
	"gin-sns/app/model/constants"
	followModel "gin-sns/app/model/module/follow"
	"gin-sns/app/service/render"
	"time"

	"github.com/gin-gonic/gin"

	"gin-sns/app/ginframe/utils/convert"
	"gin-sns/app/ginframe/utils/page"
)

var FollowService = newFollowService()

func newFollowService() *followService {
	return &followService{}
}

type followService struct {
}

//根据主键查询数据
func (s *followService) SelectRecordById(id int64) (*followModel.Entity, error) {
	return follow.FollowDao.SelectById(id)
}

//
func (s *followService) SelectRecordsIn(idarr []int64) ([]followModel.Entity, error) {

	list, err := follow.FollowDao.FindIn("id", idarr)
	if list != nil && len(list) > 0 {
		err = errors.New("not found")
		list = nil
	}
	return list, err
}

//根据主键删除数据
func (s *followService) DeleteRecordById(id int64) bool {
	return follow.FollowDao.DeleteById(id)
}

//批量删除数据记录
func (s *followService) DeleteRecordByIds(ids string) int64 {
	ida := convert.ToInt64Array(ids, ",")
	result, err := follow.FollowDao.DeleteBatch(ida...)
	if err != nil {
		return 0
	}
	return result
}

//添加数据
func (s *followService) AddSave(req *followModel.AddReq, ctx *gin.Context) (int64, error) {
	var entity followModel.Entity

	//entity.Id = req.Id
	entity.UserId = req.UserId
	entity.EntityType = req.EntityType
	entity.EntityId = req.EntityId
	entity.CreateTime = time.Now()
	//entity.CreateBy = ""

	//user := system.UserService.GetProfile(ctx)

	//if user != nil {
	//	entity.CreateBy = user.LoginName
	//}

	_, err := follow.FollowDao.Insert(&entity)
	return entity.Id, err
}

//修改数据
func (s *followService) EditSave(req *followModel.EditReq, ctx *gin.Context) (int64, error) {
	entity := &followModel.Entity{Id: req.Id}
	ok, err := follow.FollowDao.FindOne(entity)

	if err != nil {
		return 0, err
	}

	if !ok {
		return 0, errors.New("数据不存在")
	}

	entity.UserId = req.UserId
	entity.EntityType = req.EntityType
	entity.EntityId = req.EntityId
	//entity.UpdateTime = time.Now()
	//entity.UpdateBy = ""

	//user := system.UserService.GetProfile(ctx)

	//if user == nil {
	//	entity.UpdateBy = user.LoginName
	//}

	return follow.FollowDao.Update(entity)
}

//根据条件查询数据
func (s *followService) SelectListAll(params *followModel.SelectPageReq) ([]followModel.Entity, error) {
	return follow.FollowDao.SelectListAll(params)
}

//根据条件分页查询数据
func (s *followService) SelectListByPage(params *followModel.SelectPageReq) ([]followModel.Entity, *page.Paging, error) {
	return follow.FollowDao.SelectListByPage(params)
}

// 导出excel
func (s *followService) Export(param *followModel.SelectPageReq) (string, error) {
	head := []string{"", "关注者id", "实体类型", "实体id", "添加时间"}
	col := []string{"id", "user_id", "entity_type", "entity_id", "create_time"}
	return follow.FollowDao.SelectListExport(param, head, col)
}

func (s *followService) DeleteByUserIdAndFollowId(userId int64, followedId int64) error {
	entity := &followModel.Entity{UserId: userId,
		EntityType: constants.EntityTypeUser,
		EntityId:   followedId}

	follow.FollowDao.FindOne(entity)

	follow.FollowDao.Delete(entity)
	return nil
}

// 统计数量
func (s *followService) CountRssFollow(id int64) int64 {

	return follow.FollowDao.Count(constants.EntityTypeRss, id)
}

// 最近点赞
func (s *followService) GetRecent(entityType int, entityId int64, count int) []followModel.Entity {
	list, err := follow.FollowDao.GetNewestFollows(entityType, entityId, count)
	if err != nil {
		return nil
	}

	return list
}

func (s *followService) CountTopicFollow(id int64) int64 {

	return follow.FollowDao.Count(constants.EntityTypeTopic, id)
}

func (s *followService) CountCommentFollow(id int64) int64 {

	return follow.FollowDao.Count(constants.EntityTypeComment, id)
}

func (s *followService) Follow(userId int64, rssId int64) error {
	rss, _ := RssService.SelectRecordById(rssId)
	if rss == nil || rss.Status != model.StatusOk {
		return errors.New("话题不存在")
	}

	// 判断是否已经点赞了
	if s.Exists(userId, constants.EntityTypeRss, rssId) {
		return errors.New("已点赞")
	}

	// 点赞
	entity := &followModel.Entity{
		UserId:     userId,
		EntityId:   rssId,
		EntityType: constants.EntityTypeRss,
		CreateTime: time.Now(),
	}

	_, err := follow.FollowDao.Insert(entity)
	if err != nil {
		return err
	}

	// 更新帖子点赞数
	RssService.IncrFollowCount(rssId)
	return nil

}

// 统计数量
func (s *followService) Count(entityType int, entityId int64) int64 {

	return follow.FollowDao.Count(entityType, entityId)

}

// 最近点赞
func (s *followService) GetRecentUsers(entityType int, entityId int64, count int) []model.UserInfo {
	follows, _ := follow.FollowDao.GetNewestFollows(entityType, entityId, count)

	var users []model.UserInfo
	for _, follow := range follows {
		//userInfo := render.BuildUserById(follow.UserId)
		user, err := user.UserDao.SelectById(follow.UserId)
		if err == nil && user != nil {
			userInfo := render.BuildUser(user)

			if userInfo != nil {
				users = append(users, *userInfo)
			}
		}
	}

	return users
}

// Exists 是否点赞
func (s *followService) Exists(userId int64, entityType int, entityId int64) bool {

	entity := &followModel.Entity{
		UserId:     userId,
		EntityType: entityType,
		EntityId:   entityId,
	}

	have, _ := follow.FollowDao.FindOne(entity)

	return have

}

// 是否点赞，返回已点赞实体编号
func (s *followService) IsFollowd(userId int64, entityType int, entityIds []int64) []int64 {

	return follow.FollowDao.IsFollowd(userId, entityType, entityIds)
}

// TOPIC
func (s *followService) TopicFollow(userId int64, topicId int64) error {
	topic, _ := TopicService.SelectRecordById(topicId)
	if topic == nil || topic.Status != constants.StatusOk {
		return errors.New("话题不存在")
	}

	if err := s.follow(userId, constants.EntityTypeTopic, topicId); err != nil {
		return err
	}

	// 更新点赞数
	TopicService.IncrFollowCount(topicId)

	// 发送消息
	//messageService.SendTopicFollowMsg(topicId, userId)

	return nil
}

func (s *followService) CancelTopicFollow(userId int64, topicId int64) error {
	topic, _ := TopicService.SelectRecordById(topicId)
	if topic == nil || topic.Status != constants.StatusOk {
		return errors.New("话题不存在")
	}

	if !s.Exists(userId, constants.EntityTypeTopic, topicId) {
		return nil
	}

	if err := s.cancel_follow(userId, constants.EntityTypeTopic, topicId); err != nil {
		return err
	}

	// 更新点赞数
	TopicService.DecrFollowCount(topicId)

	// 发送消息
	//messageService.SendRssFollowMsg(rssId, userId)

	return nil
}

// USER
func (s *followService) UserFollow(userId int64, followUserId int64) error {
	topic, _ := TopicService.SelectRecordById(followUserId)
	if topic == nil || topic.Status != constants.StatusOk {
		return errors.New("话题不存在")
	}

	if err := s.follow(userId, constants.EntityTypeUser, followUserId); err != nil {
		return err
	}

	// 更新点赞数
	TopicService.IncrFollowCount(followUserId)

	// 发送消息
	//MessageService.SendTopicFollowMsg(followUserId, userId)

	return nil
}

func (s *followService) CancelUserFollow(userId int64, followUserId int64) error {
	followUser, _ := UserService.SelectRecordById(followUserId)
	if followUser == nil || followUser.Status != constants.StatusOk {
		return errors.New("话题不存在")
	}

	if !s.Exists(userId, constants.EntityTypeUser, followUserId) {
		return nil
	}

	if err := s.cancel_follow(userId, constants.EntityTypeTopic, followUserId); err != nil {
		return err
	}

	// 更新点赞数
	UserService.DecrFollowCount(followUserId)

	// 发送消息
	//MessageService.SendRssFollowMsg(rssId, userId)

	return nil
}

// RSS
func (s *followService) RssFollow(userId int64, followUserId int64) error {
	followUser, _ := UserService.SelectRecordById(followUserId)
	if followUser == nil || followUser.Status != constants.StatusOk {
		return errors.New("话题不存在")
	}

	if err := s.follow(userId, constants.EntityTypeTopic, followUserId); err != nil {
		return err
	}

	// 更新点赞数
	UserService.IncrFollowCount(followUserId)

	// 发送消息
	//messageService.SendRssFollowMsg(followUserId, userId)

	return nil
}

func (s *followService) CancelRssFollow(userId int64, rssId int64) error {
	rss, _ := RssService.SelectRecordById(rssId)
	if rss == nil || rss.Status != constants.StatusOk {
		return errors.New("话题不存在")
	}

	if !s.Exists(userId, constants.EntityTypeRss, rssId) {
		return nil
	}

	if err := s.cancel_follow(userId, constants.EntityTypeRss, rssId); err != nil {
		return err
	}

	// 更新点赞数
	RssService.DecrFollowCount(rssId)

	// 发送消息
	//MessageService.SendRssFollowMsg(rssId, userId)

	return nil
}

//OK
func (s *followService) follow(userId int64, entityType int, entityId int64) error {
	// 判断是否已经点赞了
	if s.Exists(userId, entityType, entityId) {
		return errors.New("已点赞")
	}
	// 点赞
	entity := &followModel.Entity{
		UserId:     userId,
		EntityType: entityType,
		EntityId:   entityId,
		CreateTime: time.Now(),
	}

	_, err := follow.FollowDao.Insert(entity)

	return err
}

func (s *followService) cancel_follow(userId int64, entityType int, entityId int64) error {
	// 判断是否已经点赞了
	if s.Exists(userId, entityType, entityId) {
		//return errors.New("已点赞")
		// 点赞
		entity := &followModel.Entity{
			UserId:     userId,
			EntityType: entityType,
			EntityId:   entityId,
			//CreateTime: time.Now(),
		}
		_, err := follow.FollowDao.FindOne(entity) //find

		_, err = follow.FollowDao.Delete(entity) //delete
		return err
	}

	return nil
}

func (s *followService) GetUserNewestFollowedIds(userId int64, limit int) ([]int64, error) {
	return follow.FollowDao.GetUserNewestFollowedIds(userId, limit)

}
func (s *followService) GetUserNewestFollowIds(userId int64, limit int) ([]int64, error) {
	return follow.FollowDao.GetUserNewestFollowIds(userId, limit)

}
